package math2;

/**
 * Lagrange basis on 4-node quadrilateral element
 * 
 * @author hbui
 * 
 */
public class LagrangeFBOnQ4 extends PolynomialBasisOnRnToR {

	public LagrangeFBOnQ4() {

		addBasisFunction(
		/*
		 * N1 = (1 - xi)(1 - eta)/4
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return (1 - xi) * (1 - eta) / 4;
			}

			@Override
			public double[] gradientAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return new double[] { -(1 - eta) / 4, -(1 - xi) / 4 };
			}
		},
		/*
		 * N2 = (1 + xi)(1 - eta)/4
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return (1 + xi) * (1 - eta) / 4;
			}

			@Override
			public double[] gradientAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return new double[] { (1 - eta) / 4, -(1 + xi) / 4 };
			}
		},
		/*
		 * N3 = (1 + xi)(1 + eta)/4
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return (1 + xi) * (1 + eta) / 4;
			}

			@Override
			public double[] gradientAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return new double[] { (1 + eta) / 4, (1 + xi) / 4 };
			}
		},
		/*
		 * N4 = (1 - xi)(1 + eta)/4
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return (1 - xi) * (1 + eta) / 4;
			}

			@Override
			public double[] gradientAt(double... psi) {
				double xi = psi[0];
				double eta = psi[1];
				return new double[] { -(1 + eta) / 4, (1 - xi) / 4 };
			}
		});
	}

	@Override
	public int getP() {
		return 2;
	}

	@Override
	public void setP(int p) {
	}

	@Override
	public Object clone() {
		return new LagrangeFBOnQ4();
	}

}
